package cn.iocoder.an.module.mold.job;

import cn.iocoder.an.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.an.framework.quartz.core.handler.JobHandler;
import cn.iocoder.an.framework.tenant.core.job.TenantJob;
import cn.iocoder.an.module.business.dal.dataobject.equipmentmanage.EquipmentManageDO;
import cn.iocoder.an.module.mold.dal.dataobject.equipmnetkeepwait.EquipmnetKeepWaitDO;
import cn.iocoder.an.module.business.dal.dataobject.warningconfig.WarningConfigDO;
import cn.iocoder.an.module.business.dal.mysql.equipmentmanage.EquipmentManageMapper;
import cn.iocoder.an.module.mold.dal.mysql.equipmnetkeepwait.EquipmnetKeepWaitMapper;
import cn.iocoder.an.module.business.dal.mysql.warningconfig.WarningConfigMapper;
import cn.iocoder.an.module.business.utils.WeComMessageUtil;
import cn.iocoder.an.module.system.api.notify.NotifyMessageSendApi;
import cn.iocoder.an.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
import cn.iocoder.an.module.system.dal.dataobject.dict.DictDataDO;
import cn.iocoder.an.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.an.module.system.service.dict.DictDataService;
import cn.iocoder.an.module.system.service.user.AdminUserService;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class WarningMessageSendJobDamage implements JobHandler {

    @Resource
    private WarningConfigMapper warningConfigMapper;

    @Autowired
    private EquipmnetKeepWaitMapper equipmnetKeepWaitMapper;

    @Resource
    private AdminUserService userService;

    @Autowired
    private WeComMessageUtil weComMessageUtil;

    @Resource
    private NotifyMessageSendApi notifySendApi;

    @Resource
    private DictDataService dictDataService;
    @Autowired
    private EquipmentManageMapper equipmentManageMapper;


    @Override
    @TenantJob // 标记多租户
    public String execute(String param) throws Exception {
        //1.先获取预警配置项 按照预警天数从小到大排序
        LambdaQueryWrapperX<WarningConfigDO> configWrapper = new LambdaQueryWrapperX<>();
        configWrapper.eq(WarningConfigDO::getWarningType,5);
        configWrapper.orderByAsc(WarningConfigDO::getWarningDays);
        List<WarningConfigDO> configList = warningConfigMapper.selectList(configWrapper);
        if (CollectionUtils.isEmpty(configList)) {
            return "error";
        }

        //2.获取预警天数最大的
        WarningConfigDO first = configList.getFirst();
        Integer maxWarningDays = first.getWarningDays();
        //获取当前日期 加上warningDays 计算未来的日期：当前日期加上预警天数
        LocalDate currentDate = LocalDate.now();
        LocalDate futureDate = currentDate.plusDays(maxWarningDays);

        //3. 查询待保养设备：计划保养日期 <= futureDate 的所有记录
        LambdaQueryWrapperX<EquipmnetKeepWaitDO> waitWrapper = new LambdaQueryWrapperX<>();
        // 添加条件：计划保养日期 大于等于 今天
        waitWrapper.ge(EquipmnetKeepWaitDO::getPlanDate, currentDate);
        // 添加条件：计划保养日期 小于等于 futureDate
        waitWrapper.le(EquipmnetKeepWaitDO::getPlanDate, futureDate);
        // 添加条件：计划保养日期 不为空 (排除 null 值)
        waitWrapper.isNotNull(EquipmnetKeepWaitDO::getPlanDate);
        List<EquipmnetKeepWaitDO> waitDOList = equipmnetKeepWaitMapper.selectList(waitWrapper);

        //4.判断
        for (EquipmnetKeepWaitDO waitDO : waitDOList) {
            LocalDate planDate = waitDO.getPlanDate();
            // 计算 planDate 与 currentDate 之间的天数差
            long daysBetween = currentDate.until(planDate, ChronoUnit.DAYS);
            for (WarningConfigDO config : configList) {
                Integer warningDays = config.getWarningDays();
                // 预警一次 避免重复预警
                if (daysBetween <= warningDays) {
                    sendKeepMessage(config.getWarningUser(),planDate, waitDO);
                    break;
                }
            }
        }
        return "success";
    }

    public void sendKeepMessage(List<Long> dutyUserId,LocalDate planDate,EquipmnetKeepWaitDO waitDO) {
        //推送消息
        List<AdminUserDO> userList = userService.getUserList(dutyUserId);
        String userIds = "";
        StringBuilder userIdBuilder = new StringBuilder();

        EquipmentManageDO equipmentManageDO = equipmentManageMapper.selectById(waitDO.getEquipmentId());

        // 获取当前时间并格式化
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String formattedNow = now.format(formatter);

        for (AdminUserDO user : userList) {
            // 1. 推送系统消息 准备参数
            String templateCode = "warning-6"; // 站内信模版，记得在【站内信管理】中配置噢
            Map<String, Object> templateParams = new HashMap<>();
            templateParams.put("planDate", formattedNow);
            NotifySendSingleToUserReqDTO sendToUserDTO = new NotifySendSingleToUserReqDTO();
            sendToUserDTO.setUserId(user.getId());
            sendToUserDTO.setTemplateCode(templateCode);
            sendToUserDTO.setTemplateParams(templateParams);
            Long l = notifySendApi.sendSingleMessageToAdmin(sendToUserDTO);
            System.out.printf("系统内消息通知:", l);

            String userId = weComMessageUtil.getUserIdByMobile(user.getEnterpriseWeChatAccount());
            if (userId != null && !userId.trim().isEmpty()) {
                // 如果已经有内容了，先添加分隔符
                if (userIdBuilder.length() > 0) {
                    userIdBuilder.append("|");
                }
                userIdBuilder.append(userId);
            }
        }

        // 将 StringBuilder 转换为最终的字符串
        userIds = userIdBuilder.toString();
        // 可选：检查最终结果是否为空
        if (userIds.isEmpty()) {
            // 处理没有找到任何有效用户ID的情况
            System.out.printf("没有找到任何有效的企业微信 UserID");
            return;
        }

        // 1. 使用 sendTextMessage 方法 (更灵活，可以同时指定用户、部门、标签)

        //从字典配置中获取发送的消息
        DictDataDO wxMessage = dictDataService.getDictData("by_message", "2");

        //消息通知优化：设备保养预警通知：您有新的设备待保养，设备编号如下：【xxxxxx】，设备安装位置：【xxxx】，计划保养日期为：2025-09-02 请规划时间完成设备保养工作
        String text = "设备维护预警通知：您有新的易损设备待维护，设备编号如下：【" + equipmentManageDO.getCode() +  "】，设备安装位置：【"+equipmentManageDO.getInstallPosition()+"】，计划维护日期为：" + planDate +"请规划时间完成设备维护工作。";


        String systemMessage = text + formattedNow;
        // 将时间戳添加到消息中
        WeComMessageUtil.WeComSendResult weComSendResult = weComMessageUtil.sendTextMessage(systemMessage, userIds, null, null);
        System.out.printf("推送结果:" + weComSendResult.toString());

    }


}
